using System;
using System.ComponentModel;
using System.Linq.Expressions;
using InfiniTec.Threading;

namespace InfiniTec
{
	public static class EventHandlerExtension
	{
		public static void Raise(this PropertyChangedEventHandler eventHandler, object sender, PropertyChangedEventArgs e)
		{
			if (e == null) throw new ArgumentNullException("e");
			if (eventHandler != null)
			{
				eventHandler(sender, e);
			}
		}

		public static void Raise(this EventHandler eventHandler, object sender, EventArgs e)
		{
			if (e == null) throw new ArgumentNullException("e");
			if (eventHandler != null)
			{
				eventHandler(sender, e);
			}
		}

        public static void Raise<T>(this PropertyChangedEventHandler eventHandler, object sender, Expression<Func<T>> mapping)
        {
            var name = mapping.GetPropertyName();

            eventHandler.Raise(sender, name);
        }

		public static void Raise(this EventHandler eventHandler, object sender)
		{
			eventHandler.Raise(sender, EventArgs.Empty);
		}

		public static void Raise(this PropertyChangedEventHandler eventHandler, object sender, string propertyName)
		{
			eventHandler.Raise(sender, new PropertyChangedEventArgs(propertyName));
		}

		public static void Raise(this ProgressChangedEventHandler eventHandler, object sender, ProgressChangedEventArgs e)
		{
			if (e == null) throw new ArgumentNullException("e");
			if (eventHandler != null)
			{
				eventHandler(sender, e);
			}
		}
		public static void Raise<T>(this AsyncCompletedEventHandler<T> eventHandler, object sender, AsyncCompletedEventArgs<T> e)
		{
			if (e == null) throw new ArgumentNullException("e");
			if (eventHandler != null)
			{
				eventHandler(sender, e);
			}
		}
		public static void Raise(this AsyncCompletedEventHandler eventHandler, object sender, AsyncCompletedEventArgs e)
		{
			if (e == null) throw new ArgumentNullException("e");
			if (eventHandler != null)
			{
				eventHandler(sender, e);
			}
		}

		public static void Raise<T>(this EventHandler<T> eventHandler, object sender, T e) where T : EventArgs
		{
			if (e == null) throw new ArgumentNullException("e");
			if (eventHandler != null)
			{
				eventHandler(sender, e);
			}
		}
	}
}